package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSkuVo;
import com.spzx.product.api.domain.SkuPriceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: CartServiceImpl
 * Package: com.spzx.cart.service.impl
 * Description:
 *
 * @Author 王颖轩
 * @Create 2024/12/29 17:07
 * @Version 1.0
 */

@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    private RemoteProductService remoteProductService;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取购物车key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //hash格式
        //redisTemplate.opsForHash()
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);


        //判断购物车中是否已经存在当前商品
        String hashKey = skuId.toString();
        if(hashOps.hasKey(hashKey)){
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount> 9 ? 9 : totalCount);
            hashOps.put(hashKey, cartInfo);
        }else{

            //判断购物车商品种类（不同SKU）总数大于5件
            Long size = hashOps.size();
            if(++size > 5){
                throw new ServiceException("购物车商品种类（不同SKU）总数不能超过5件");
            }

            //远程获取商品信息
            R<ProductSkuVo> productSkuVoResult = remoteProductService.getProductSkuVo(skuId, SecurityConstants.INNER);//"inner"
            if(R.FAIL == productSkuVoResult.getCode()){
                throw new ServiceException(productSkuVoResult.getMsg());
            }
            ProductSkuVo productSkuVo = productSkuVoResult.getData();

            //组装购物车数据
            CartInfo cartInfo = new CartInfo();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSkuVo.getSkuName());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setThumbImg(productSkuVo.getThumbImg());
            cartInfo.setCartPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuPrice(productSkuVo.getSalePrice());
            cartInfo.setUserId(userId);
            cartInfo.setIsChecked(1);
            cartInfo.setCreateBy(SecurityUtils.getUsername());
            cartInfo.setCreateTime(new Date());
            hashOps.put(skuId.toString(), cartInfo);
        }

    }

    @Override
    public List<CartInfo> getCartList() {
        // 获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);

        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            //降序
            cartInfoList = cartInfoList
                    .stream()
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
        }

        return cartInfoList;
    }

    @Override
    public void deleteCart(Long skuId) {
        // 获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        hashOperations.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);

        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        // 先获取用户选择的商品
        if(hashOps.hasKey(skuId.toString())){
            CartInfo cartInfo = hashOps.get(skuId.toString());
            // cartInfoUpd 写回缓存
            cartInfo.setIsChecked(isChecked);
            // 更新缓存
            hashOps.put(skuId.toString(), cartInfo);
        }


    }

    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);

        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOperations.values();
        cartInfoList.forEach(cartInfo -> {
            CartInfo cartInfoUpd = hashOperations.get(cartInfo.getSkuId().toString());
            cartInfoUpd.setIsChecked(isChecked);
            // 更新缓存
            hashOperations.put(cartInfo.getSkuId().toString(), cartInfoUpd);
        });


    }

    @Override
    public void clearCart() {
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);

        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        Long userId = SecurityUtils.getUserId();
        String cartKey = this.getCartKey(userId);

        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList = cartInfoList
                    .stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
        }

        return cartInfoList;
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);
        HashOperations<String, String, CartInfo> hashOperations = redisTemplate.opsForHash();
        List<CartInfo> cartCachInfoList = hashOperations.values(cartKey);

        if(!CollectionUtils.isEmpty(cartCachInfoList)){
            for (CartInfo cartInfo : cartCachInfoList) {
                R<SkuPriceVo> skuPriceResult = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                if(R.FAIL == skuPriceResult.getCode()){
                    throw new ServiceException("更新购物车价格失败"+skuPriceResult.getMsg());
                }
                cartInfo.setSkuPrice(skuPriceResult.getData().getSalePrice());
                hashOperations.put(cartKey, cartInfo.getSkuId().toString(), cartInfo);
            }
        }
        return true;
    }

    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = getCartKey(userId);
        HashOperations<String, String, CartInfo> hashOperations = redisTemplate.opsForHash();
        List<CartInfo> cartCachInfoList = hashOperations.values(cartKey);
        if(!CollectionUtils.isEmpty(cartCachInfoList)){
                //删除选中商品
            cartCachInfoList.stream()
                        .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                        .forEach(cartInfo -> hashOperations.delete(cartKey, cartInfo.getSkuId().toString()));
            }
        return true;
    }


    /**
     * 获取购物车key
     * @param userId
     * @return
     */
    private String getCartKey(Long userId) {
        return "user:cart:" + userId;
    }
}

